//
//  YYStringPickerView.swift
//  DatePickerView
//
//  Created by 蓓蕾 on 2022/3/23.
//

import UIKit

class YYStringPickerView: UIView, UIPickerViewDelegate, UIPickerViewDataSource {
    
    enum YYStringPickerMode:Int {
        /** 单列选择器 */
        case YYStringPickerComponentSingle
        /** 多列选择器 */
        case YYStringPickerComponentMulti
        /** 多级联动选择器 */
        case YYStringPickerComponentLinkage
    }
    
    typealias YYStringResultBlock=(YYResultModel)->Void
    typealias YYStringResultModelArrayBlock=(NSArray,NSDictionary)->Void
    var selectResultBlock: YYStringResultBlock?
    var selectResultArrBlock : YYStringResultModelArrayBlock?
    
    let systemBlackColr = UIColor(hex: 0x424243)//系统常用的黑色
    let systemgrayColor = UIColor(hex: 0xb2b2b2)//系统常用的灰色
    
    var CancelReturnBlock: (() -> Void)? //取消按钮的回调
    private lazy var linkPickerView = false//自定义数据联动选择器
    
    private lazy var selectModelArr = NSMutableArray()
    private lazy var selectModelDic = NSMutableDictionary()
    
    var bgView : UIView?
    private lazy var titleView = UILabel()
    private lazy var cancelButton = UIButton()
    private lazy var confirmButton = UIButton()
    var lineView = UIView()//一条横线
    var pickerView = UIPickerView()
    
    var BorderHeight = 400
    var PickerColumnNumber = 1
    var currentStringPickerMode = YYStringPickerMode.YYStringPickerComponentSingle
    
//    private var resultSelectDateStringValue : String!
    /// 默认选中
    private var initialSelectString = ""
    private var initialSelectIndex = -1
    private lazy var initialSelectItemArr = NSArray()
    private lazy var initialSelectIndexArr = NSArray()
    
    //数据相关
    private var dataSource = NSArray()
    private var resultModel = YYResultModel()
    
    static let shared = YYStringPickerView()
    
    private override init(frame: CGRect) {
        super.init(frame: frame)
        print("init 方法")
        initUI()
        initData()
    }
    
    override func copy() -> Any {
        print("copy 方法")
        return self // SingletonClass.shared
    }
    
    override func mutableCopy() -> Any {
        print("mutableCopy 方法")
        return self // SingletonClass.shared
    }
    
    func reset() {
        print("reset 方法")
    }
    
    private func initUI(){
        let boundsSizeWidth:CGFloat = UIScreen.main.bounds.width
        let boundsSizeHeight:CGFloat = UIScreen.main.bounds.height
        self.frame = CGRect(x: 0, y: 0, width: boundsSizeWidth, height: boundsSizeHeight)
//        self.backgroundColor = UIColor.white
//        if bgView == nil {
//            bgView = UIView(frame: UIScreen.main.bounds)
//        }
//        if bgView!.superview == nil {
//            getWindow().addSubview(bgView!)
//        }
        
        pickerView.frame = CGRect(x: 0, y: Int(boundsSizeHeight) - BorderHeight, width: Int(boundsSizeWidth), height: BorderHeight)
        pickerView.delegate = self
        pickerView.dataSource = self
        self.addSubview(pickerView)
        
        
        let topBgView = UIView()
        self.addSubview(topBgView)
        topBgView.frame = CGRect(x: 0, y: pickerView.frame.minY + 5, width: boundsSizeWidth, height: 40)
        topBgView.backgroundColor = .white
        
        
        lineView.frame = CGRect(x: 15, y: topBgView.bounds.height - 1, width: topBgView.bounds.width - 30, height: 1)
        lineView.backgroundColor = UIColor.systemGray
        topBgView.addSubview(lineView)
        
        cancelButton.frame = CGRect(x: 15, y: (topBgView.bounds.height - 20) / 2, width: 50, height: 20)
        cancelButton.setTitle("取消", for: .normal)
        cancelButton.setTitleColor(UIColor.system, for: .normal)
        cancelButton.titleLabel?.font = UIFont.systemFont(ofSize: 15)
        cancelButton.tag = 101
        cancelButton.addTarget(self, action: #selector(buttonClick), for: .touchUpInside)
        topBgView.addSubview(cancelButton)
        
        confirmButton.frame = CGRect(x: boundsSizeWidth - 50 - 15, y: cancelButton.frame.minY, width: 50, height: 20)
        confirmButton.setTitle("确定", for: .normal)
        confirmButton.setTitleColor(UIColor.system, for: .normal)
        confirmButton.titleLabel?.font = UIFont.systemFont(ofSize: 15)
        confirmButton.tag = 102
        confirmButton.addTarget(self, action: #selector(buttonClick), for: .touchUpInside)
        topBgView.addSubview(confirmButton)
        
        let titleViewX = cancelButton.frame.maxX + 15
        titleView.frame = CGRect(x: titleViewX, y: (topBgView.bounds.height - 20) / 2, width: confirmButton.frame.minX - 15 - titleViewX, height: 20)
        titleView.textColor = systemBlackColr
        titleView.textAlignment = .center
        titleView.font = UIFont.systemFont(ofSize: 15)
        titleView.text = "选择时间"
        topBgView.addSubview(titleView)
        
        
    }
    
    //MARK: 初始化数据
    private func initData()  {
        switch currentStringPickerMode {
        case .YYStringPickerComponentSingle:
            if initialSelectIndex >= 0 && dataSource.count > initialSelectIndex {
                let model = dataSource[initialSelectIndex]
                if model is YYResultModel {
                    resultModel = model as! YYResultModel
                } else if model is String {
                    let currentString:String = model as! String
                    resultModel.value = currentString
                } else {
                    
                }
                pickerView.reloadAllComponents()
                pickerView.selectRow(initialSelectIndex, inComponent: 0, animated: true)
            } else if initialSelectString.count > 0 {
                
                for (index, obj) in dataSource.enumerated() {
                    if obj is YYResultModel {
                        let currentModel:YYResultModel = obj as! YYResultModel
                        if currentModel.value == initialSelectString {
                            print("找到了，结束循环")
                            resultModel = currentModel
                            initialSelectIndex = index
                            break
                        }
                    } else if obj is String {
                        let currentString:String = obj as! String
                        if currentString == initialSelectString {
                            print("找到了，结束循环")
                            resultModel.value = currentString
                            initialSelectIndex = index
                            break
                        }
                    } else {

                    }
                }
                
                
                pickerView.reloadAllComponents()
                pickerView.selectRow(initialSelectIndex, inComponent: 0, animated: true)
            } else {
                pickerView.reloadAllComponents()
                pickerView.selectRow(0, inComponent: 0, animated: true)
            }
        case .YYStringPickerComponentMulti:
//            print("dataSource = \(dataSource)")
            PickerColumnNumber = dataSource.count
            pickerView.reloadAllComponents()
            for i in 0..<PickerColumnNumber {
                pickerView.selectRow(0, inComponent: i, animated: true)
                let itemData = dataSource[i]
                if itemData is NSArray {
                    let currentItemArr:NSArray = itemData as! NSArray
                    let currentItem = currentItemArr.firstObject
                    if currentItem is String {
                        let currentItemString:String = currentItem as! String
                        let model = YYResultModel()
                        model.value = currentItemString
                        selectModelDic.setValue(model, forKey: String(i))
                    } else if currentItem is YYResultModel {
                        let model:YYResultModel = currentItem as! YYResultModel
                        selectModelDic.setValue(model, forKey: String(i))
                    }
                }
                
                
            }
            
            if initialSelectIndexArr.count > 0 {
                print("通过index来确定默认选项")
                for i in 0..<PickerColumnNumber {
                    let itemData = dataSource[i]
                    if itemData is NSArray {
                        let currentItemArr:NSArray = itemData as! NSArray
                        guard i < initialSelectIndexArr.count else {
//                            print("结束本次循环，开始下次循环")
//                            continue
                            print("结束本次循环")
                            break
                        }
                        let selectIndexString:String = initialSelectIndexArr[i] as! String
                        var selectIndex:Int = Int(selectIndexString) ?? 0
                        selectIndex = selectIndex < currentItemArr.count ? selectIndex : 0
                        let currentItem = currentItemArr[selectIndex]
                        if currentItem is String {
                            let currentItemString:String = currentItem as! String
                            let model = YYResultModel()
                            model.value = currentItemString
                            selectModelDic.setValue(model, forKey: String(i))
                        } else if currentItem is YYResultModel {
                            let model:YYResultModel = currentItem as! YYResultModel
                            selectModelDic.setValue(model, forKey: String(i))
                        }
                        pickerView.selectRow(selectIndex, inComponent: i, animated: true)
                    }
                }
            } else if initialSelectItemArr.count > 0 {
                print("通过item来确定默认选项")
                
                
                for i in 0..<PickerColumnNumber {
                    guard i < initialSelectItemArr.count else {
                        print("结束本次循环")
                        break
                    }
                    let selectItem = initialSelectItemArr[i]
                    
                    let itemData = dataSource[i]
                    if itemData is NSArray {
                        let currentItemArr:NSArray = itemData as! NSArray
                        let selectItem = initialSelectItemArr[i]
                        var selectValueString:String = ""
                        if selectItem is String {
                            selectValueString = selectItem as! String
                        } else if selectItem is YYResultModel {
                            let model:YYResultModel = selectItem as! YYResultModel
                            selectValueString = model.value ?? "value"
                        }
                        
                        for j in 0..<currentItemArr.count {
                            let item = currentItemArr[j]
                            if item is String && item as! String == selectValueString {
                                print("已找到，结束本次循环")
                                let model = YYResultModel()
                                model.value = selectValueString
                                selectModelDic.setValue(model, forKey: String(i))
                                pickerView.selectRow(j, inComponent: i, animated: true)
                                break
                            } else if item is YYResultModel {
                                let model:YYResultModel = item as! YYResultModel
                                if model.value == selectValueString {
                                    selectModelDic.setValue(model, forKey: String(i))
                                    pickerView.selectRow(j, inComponent: i, animated: true)
                                    print("已找到，结束本次循环")
                                    break
                                }
                            }
                        }
                    }
                }
                
                
                
            } else {
                
            }
            
        case .YYStringPickerComponentLinkage:
            if linkPickerView {
                
            } else {
                PickerColumnNumber = dataSource.count
            }
            
            pickerView.reloadAllComponents()
        }
        
        
//        pickerView.selectRow(0, inComponent: 1, animated: true)
//        pickerView.selectRow(0, inComponent: 2, animated: true)
    }
    
    //MARK: JSONString转换为数组
    private func changeJsonToArray(jsonString:String) ->NSArray{
        let jsonData:Data = jsonString.data(using: .utf8)!
        let array = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
        if array != nil {
            return array as! NSArray
        }
        return NSArray()
    }
    
    //MARK: 按钮的响应事件
    @objc private func buttonClick(btn:UIButton){
        let tag:Int = btn.tag
        switch tag {
        case 101:
            dismissDatePickerView()
        case 102:
            dismissDatePickerView()
            
            switch currentStringPickerMode {
            case .YYStringPickerComponentSingle:
                if self.selectResultBlock != nil {
                    let model:YYResultModel = resultModel
                    self.selectResultBlock!(model)
                }
            case .YYStringPickerComponentMulti:
                if self.selectResultArrBlock != nil {
                    let keysCount:Int = selectModelDic.allKeys.count
                    selectModelArr.removeAllObjects()
                    for i in 0..<keysCount {
                        let currentItem = selectModelDic.object(forKey: String(i))
                        selectModelArr.add(currentItem ?? "value")
                    }
                    self.selectResultArrBlock!(selectModelArr, selectModelDic)
                }
            case .YYStringPickerComponentLinkage:
                if self.selectResultBlock != nil {
                    let model:YYResultModel = resultModel
                    self.selectResultBlock!(model)
                }
            }
            
            
        default:
            break
        }
    }
    
    //MARK: UIPickerViewDataSource
    
    //返回UIPickerView当前的列数
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return PickerColumnNumber
    }
    //确定每一列返回的东西
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        
        switch currentStringPickerMode {
        case .YYStringPickerComponentSingle:
            return dataSource.count
        case .YYStringPickerComponentMulti:
            let itemData = dataSource[component]
            if itemData is NSArray {
                let itemArr:NSArray = itemData as! NSArray
                return itemArr.count
            }
            return 0
        case .YYStringPickerComponentLinkage:
            if linkPickerView {
                let itemData = dataSource[component]
                if itemData is YYResultModel {
                    let model:YYResultModel = itemData as! YYResultModel
                    if component == 0 {
                        return dataSource.count
                    } else {
                        let sunArr:NSArray = model.sunDataArr ?? NSArray();
                        return sunArr.count
                    }
                    
                }
            }
            return dataSource.count
        }
        
//        switch component {
//        case 0:
//            return dataSource.count
////        case 1:
////            return provinceResultModel.citylist.count
////        case 2:
////            return cityResultModel.arealist.count
//        default:
//            return 0
//        }
    }
    //MARK: UIPickerViewDelegate
    
    //返回一个视图，用来设置pickerView的每行显示的内容。
    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        let boundsSizeWidth = UIScreen.main.bounds.width
        let labelView = UILabel(frame: CGRect(x: boundsSizeWidth * CGFloat(component) / 6, y: 0, width: boundsSizeWidth / 6, height: 30))
        labelView.font = UIFont.systemFont(ofSize: 15)
        labelView.tag = component*100+row
        labelView.textAlignment = .center
        
        switch currentStringPickerMode {
        case .YYStringPickerComponentSingle:
            labelView.frame=CGRect(x:0, y:0,width:boundsSizeWidth - 10, height:30)
            let model = dataSource[row]
            if model is YYResultModel {
                let currentResultModel:YYResultModel = model as! YYResultModel
                let currentString:String = currentResultModel.value ?? "value"
                labelView.text = currentString
            } else if model is String {
                let currentString:String = model as! String
                labelView.text = currentString
            } else {
                
            }
        case .YYStringPickerComponentMulti:
            let itemData = dataSource[component]
            if itemData is NSArray {//2-40,3-10
                let margin:Int = PickerColumnNumber == 2 ? 40 : 10
                labelView.frame=CGRect(x:0, y:0,width:(Int(boundsSizeWidth) / PickerColumnNumber) - margin, height:30)
                let itemArr:NSArray = itemData as! NSArray
                let currentItemData = itemArr[row]
                if currentItemData is String {
                    let currentString:String = currentItemData as! String
                    labelView.text = currentString;
                } else if currentItemData is YYResultModel {
                    let model:YYResultModel = currentItemData as! YYResultModel
                    labelView.text = model.value;
                }
            }
            
//            if component == 0 && row == 0 {
//                labelView.backgroundColor = .brown
//            } else if component == 1 && row == 1 {
//                labelView.backgroundColor = .red
//            } else if component == 2 && row == 2 {
//                labelView.backgroundColor = .systemGray
//            } else if component == 3 && row == 3 {
//                labelView.backgroundColor = .systemRed
//            } else if component == 4 && row == 4 {
//                labelView.backgroundColor = .systemRed
//            } else if component == 5 && row == 5 {
//                labelView.backgroundColor = .systemRed
//            } else if component == 6 && row == 2 {
//                labelView.backgroundColor = .systemRed
//            }
            
        case .YYStringPickerComponentLinkage:
            if linkPickerView {
                let margin:Int = PickerColumnNumber == 2 ? 40 : 10
                labelView.frame=CGRect(x:0, y:0,width:(Int(boundsSizeWidth) / PickerColumnNumber) - margin, height:30)
                let itemData = dataSource[component]
                if itemData is YYResultModel {
                    let model:YYResultModel = itemData as! YYResultModel
                    if component == 0 {
                        labelView.text = model.value
                    } else {
                        let itemArr:NSArray = model.sunDataArr ?? NSArray()
                        let currentItem = itemArr[row]
                        if currentItem is NSDictionary {
                            let currentItemDic:NSDictionary = currentItem as! NSDictionary
                            labelView.text = currentItemDic[model.sunDataValueKey ?? ""] as? String
                        } else if currentItem is String {
                            let currentItemString:String = currentItem as! String
                            labelView.text = currentItemString
                        }
                    }
                }
            }
//            if component == 0 && row == 0 {
//                labelView.backgroundColor = .brown
//            } else if component == 1 && row == 1 {
//                labelView.backgroundColor = .red
//            } else if component == 2 && row == 2 {
//                labelView.backgroundColor = .systemGray
//            } else if component == 3 && row == 3 {
//                labelView.backgroundColor = .systemRed
//            } else if component == 4 && row == 4 {
//                labelView.backgroundColor = .systemRed
//            } else if component == 5 && row == 5 {
//                labelView.backgroundColor = .systemRed
//            } else if component == 6 && row == 2 {
//                labelView.backgroundColor = .systemRed
//            }
            
        }
        
        
        
        
//        switch component {
//        case 0:
//
//
//        case 1: break
////            labelView.frame=CGRect(x:0, y:0,width:boundsSizeWidth/3.0 - 10, height:30)
////            let cityArr:NSArray = provinceResultModel.citylist
////            let cityDic:NSDictionary = cityArr[row] as! NSDictionary
////            let cityString:String = cityDic["name"] as! String
////            labelView.text = cityString
//        case 2: break
////            labelView.frame=CGRect(x:0, y:0,width:boundsSizeWidth/3.0 - 10, height:30)
////            let areaArr:NSArray = cityResultModel.arealist
////            let areaDic:NSDictionary = areaArr[row] as! NSDictionary
////            let areaString:String = areaDic["name"] as! String
////            labelView.text = areaString
//        default:
//            labelView.text = ""
//        }
        return labelView
    }
    
    
    //当点击UIPickerView的某一列中某一行的时候，就会调用这个方法
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        switch currentStringPickerMode {
        case .YYStringPickerComponentSingle:
            let model = dataSource[row]
            if model is YYResultModel {
                let currentResultModel:YYResultModel = model as! YYResultModel
                resultModel = currentResultModel
            } else if model is String {
                let currentString:String = model as! String
                resultModel.value = currentString
            } else {
                
            }
        case .YYStringPickerComponentMulti:
            let itemData = dataSource[component]
            if itemData is NSArray {
                let itemArr:NSArray = itemData as! NSArray
                let currentItemData = itemArr[row]
                if currentItemData is String {
                    let currentString:String = currentItemData as! String
                    let model = YYResultModel()
                    model.value = currentString
                    selectModelDic.setValue(model, forKey: String(component))
//                    print("selectModelDic = \(selectModelDic)")
                } else if currentItemData is YYResultModel {
                    let model:YYResultModel = currentItemData as! YYResultModel
                    selectModelDic.setValue(model, forKey: String(component))
                }
            }
        case .YYStringPickerComponentLinkage:
            if linkPickerView {
                let itemData = dataSource[component]
                if itemData is YYResultModel {
                    let model:YYResultModel = itemData as! YYResultModel
                    let itemArr:NSArray = model.sunDataArr ?? NSArray()
                    let currentItem = itemArr[row]
                    if currentItem is NSDictionary {
                        let currentItemDic:NSDictionary = currentItem as! NSDictionary
//                        labelView.text = currentItemDic[model.sunDataValueKey ?? ""] as? String
                    } else if currentItem is String {
                        let currentItemString:String = currentItem as! String
//                        labelView.text = currentItemString
                    }
                    
                }
            }
        }
        
//        switch component {
//        case 0:
            
//        case 1: break
////            let cityArr:NSArray = provinceResultModel.citylist
////            let cityDic:NSDictionary = cityArr[row] as! NSDictionary
////            cityResultModel.name = cityDic["name"] as? String
////            cityResultModel.code = cityDic["code"] as? String
////            cityResultModel.arealist = cityDic["areaList"] as? NSArray
////            cityResultModel.index = row
////            self.pickerView.reloadComponent(2)
//        case 2: break
////            let areaArr:NSArray = cityResultModel.arealist
////            let areaDic:NSDictionary = areaArr[row] as! NSDictionary
////            areaResultModel.name = areaDic["name"] as? String
////            areaResultModel.code = areaDic["code"] as? String
////            areaResultModel.index = row
//        default: break
//
//        }
        
        
    }
    
    //MARK: 获取窗口window
    private func getWindow() ->UIWindow? {
        
        
        if let window:UIWindow = (UIApplication.shared.delegate?.window)! {
            return window
        }else{
            if #available(iOS 13.0, *) {
                let array:Set = UIApplication.shared.connectedScenes
                let windowScene:UIWindowScene = array.first as! UIWindowScene
                if let mainWindow:UIWindow = windowScene.value(forKeyPath:"delegate.window") as? UIWindow{
                    return mainWindow
                }else{
                    return UIApplication.shared.windows.first!
                }
            }else{
                return UIApplication.shared.keyWindow!
            }
        }
    }
    
    class private func getWindow() ->UIWindow? {
        
        return shared.getWindow()
    }
    //MARK: 单列选择器
    /// 单列选择器 根据 index 设置默认选择项
    class func showPicker(mode:YYStringPickerMode, title:String?, dataArr:NSArray, selectIndex:Int, resultBlock:@escaping YYStringResultBlock){
        if shared.superview == nil {
            getWindow()?.addSubview(shared)
        }
        print("currentDatePickerMode = \(mode)")
        shared.linkPickerView = false
        shared.dataSource = dataArr
        shared.titleView.text = title
        shared.initialSelectIndex = selectIndex
        shared.currentStringPickerMode = mode
        shared.initData()
        shared.selectResultBlock = resultBlock
    }
    /// 单列选择器 根据 String 设置默认选择项
    class func showPicker(mode:YYStringPickerMode, title:String?, dataArr:NSArray, selectString:String?, resultBlock:@escaping YYStringResultBlock){
        if shared.superview == nil {
            getWindow()?.addSubview(shared)
        }
        print("currentDatePickerMode = \(mode)")
        shared.linkPickerView = false
        shared.dataSource = dataArr
        shared.titleView.text = title
        shared.initialSelectString = selectString ?? ""
        shared.currentStringPickerMode = mode
        shared.initData()
        shared.selectResultBlock = resultBlock
    }
    //MARK: 多列选择器
    /// 多列选择器 根据 index 设置默认选择项
    class func showMulPicker(mode:YYStringPickerMode, title:String?, dataArr:NSArray, selectIndexArr:NSArray?, resultBlock:@escaping YYStringResultModelArrayBlock){
        if shared.superview == nil {
            getWindow()?.addSubview(shared)
        }
        print("currentDatePickerMode = \(mode)")
        shared.linkPickerView = false
        shared.dataSource = dataArr
        shared.titleView.text = title
        shared.initialSelectIndexArr = selectIndexArr ?? NSArray()
        shared.initialSelectItemArr = NSArray()
        shared.currentStringPickerMode = mode
        shared.initData()
        shared.selectResultArrBlock = resultBlock
    }
    /// 多列选择器 根据 String 设置默认选择项
    class func showMulPicker(mode:YYStringPickerMode, title:String?, dataArr:NSArray, selectItemArr:NSArray?, resultBlock:@escaping YYStringResultModelArrayBlock){
        if shared.superview == nil {
            getWindow()?.addSubview(shared)
        }
        print("currentDatePickerMode = \(mode)")
        shared.linkPickerView = false
        shared.dataSource = dataArr
        shared.titleView.text = title
        shared.initialSelectItemArr = NSArray()
        shared.initialSelectItemArr = selectItemArr ?? NSArray()
        shared.currentStringPickerMode = mode
        shared.initData()
        shared.selectResultArrBlock = resultBlock
    }
    /// 联动选择器
    class func showMulPicker(column:Int, title:String?, dataArr:NSArray, selectIndexArr:NSArray?, resultBlock:@escaping YYStringResultModelArrayBlock){
        if shared.superview == nil {
            getWindow()?.addSubview(shared)
        }
        shared.linkPickerView = true
        shared.dataSource = dataArr
        shared.titleView.text = title
        shared.initialSelectIndexArr = selectIndexArr ?? NSArray()
        shared.initialSelectItemArr = NSArray()
        shared.PickerColumnNumber = column
        shared.currentStringPickerMode = .YYStringPickerComponentLinkage
        shared.initData()
        shared.selectResultArrBlock = resultBlock
    }
    
    private func dismissDatePickerView(){
        self.removeFromSuperview()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError("init(coder:) has not been implemented")
    }

}
